#include "../include/itemslist.h"

#include <algorithm>

ItemsList::ItemsList() {}

map<string, string> ItemsList::getApps() {
    map<string, string> apps;

    string path = "/usr/share/applications";
	for (const auto &entry : filesystem::directory_iterator(path)) {
		mINI::INIFile ifile(entry.path());
		mINI::INIStructure ini;

		ifile.read(ini);

		string &name = ini["Desktop Entry"]["Name"];
		string &exec = ini["Desktop Entry"]["Exec"];
		string &noDisplayStr = ini["Desktop Entry"]["NoDisplay"];
		string &isTerminalStr = ini["Desktop Entry"]["Terminal"];

		bool noDisplay = stringToBool(noDisplayStr);
		bool isTerminal = stringToBool(isTerminalStr);
	
		auto findex = exec.find("%");
		if (findex != string::npos) exec = exec.substr(0, findex);

		if (noDisplay || name == "") continue;
		if (isTerminal) exec = getTerminal() + " -e " + exec;
        transform(name.begin(), name.end(), name.begin(), ::tolower);

        size_t found = name.find(" ");
        while (found != string::npos) {
            name = name.replace(found, 1, "-");
            found = name.find(" ");
        }

		apps[name] = exec;
	}
   
    return apps;
}

map<string, string> ItemsList::getScripts(string scriptsPath) {
    map<string, string> scripts;

	string homedir = getHomeDir();

	string path = homedir + "/" + scriptsPath;
	for (const auto &entry : filesystem::directory_iterator(path)) {
		string epath = entry.path();
		string exec = "sh " + epath;

		string name = epath.substr(path.length()+1, epath.length());
		name = name.substr(0, name.length()-3);

		scripts[name] = exec;
	}

    return scripts;
}

map<string, string> ItemsList::getCommands() {
    map<string, string> commands;

	string path = "/usr/bin";
	for (const auto &entry : filesystem::directory_iterator(path)) {
		string name = entry.path();
		string exec = name;

		name = name.substr(9);

		commands[name] = exec;
	}

    return commands;
}

map<string, string> ItemsList::getHistory() {  
    map<string, string> history;

    std::ifstream file(getConfigDirPath() + "/history");
    if (file.is_open()) {
        std::string line;
        char delim = '|';
        vector<string> out;
        while (std::getline(file, line)) {
            size_t found = line.find("\n");
            if (found != string::npos)
                line = line.replace(found, string("\n").length(), "");
            out.clear();
            split(line, delim, out);
            
            if (out.size() < 2) continue;
            history[out[0]] = out[1];
        }
        file.close();
    }

    return history;
}

map<string, string> ItemsList::getPart(bool includeCommands, bool includeScripts, bool includeApps) {
    map<string, string> all; 
    map<string, string> itemMap;

    if (includeCommands) {
        itemMap = this->getCommands();
        all.insert(itemMap.begin(), itemMap.end());
    }

    if (includeScripts) {
        itemMap = this->getScripts("ellie");
        all.insert(itemMap.begin(), itemMap.end());
    }

    if (includeApps) {
        itemMap = this->getApps();
        all.insert(itemMap.begin(), itemMap.end());
    }

    return all;
}

map<string, string> ItemsList::getAll() {
    map<string, string> all; 
    map<string, string> itemMap;

    itemMap = this->getCommands();
    all.insert(itemMap.begin(), itemMap.end());

    itemMap = this->getScripts("ellie");
    all.insert(itemMap.begin(), itemMap.end());

    itemMap = this->getApps();
    all.insert(itemMap.begin(), itemMap.end());

    return all;
}


